package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.mapper.AdChannelMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.aliyun.GreenImageScan;
import com.heima.aliyun.GreenTextScan;
import com.heima.common.constants.wemedia.WemediaConstants;
import com.heima.common.exception.CustomException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.wemedia.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {
    @Autowired
    WemediaFeign wemediaFeign;

    @Value("${file.oss.web-site}")
    private String webSite;

    @Resource
    AdSensitiveMapper adSensitiveMapper;

    @Autowired
    GreenTextScan greenTextScan;

    @Autowired
    GreenImageScan greenImageScan;

    @Resource
    AdChannelMapper adChannelMapper;

    @Autowired
    ArticleFeign articleFeign;
    @Override
    public void autoScanByMediaNewsId(Integer wmNewsId) {
        //检验参数
        if (wmNewsId==null){
            log.error("当前的审核id空");
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //查询该文章是否存在
        WmNews wmNews = wemediaFeign.findById(wmNewsId);
        System.out.println("wmNews = " + wmNews);
        if (wmNews==null){
            log.error("审核的自媒体文章不存在，自媒体的id:{}", wmNewsId);
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }
        //获取文章状态 判断文章状态
        if (wmNews.getStatus()==null){
            log.error("审核的自媒体文章状态不存在，自媒体的id:{}", wmNewsId);
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //状态为 4 人工审核通过   时间小于当前时间 直接发布
        if (wmNews.getStatus().equals(WmNews.Status.ADMIN_SUCCESS.getCode()) && wmNews.getPublishTime().before(new Date())){
            //发布
            publishArticle(wmNews);
            return;
        }
        //状态为 8 自动审核通过   时间小于当前时间 直接发布
        if (wmNews.getStatus().equals(WmNews.Status.SUCCESS.getCode()) && wmNews.getPublishTime().before(new Date())){
            //发布
            publishArticle(wmNews);
            return;
        }
        //状态为1  待审核状态
        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())){

            //1先抽出文章内容  以及 图片  进行自动审核
            Map<String, Object> contentAndImagesResult = handleTextAndImages(wmNews);
            //2进行 DFA 自管理敏感词  审核过滤
            //查询出所有敏感词
            List<String> allSensitive = adSensitiveMapper.findAllSensitive();
            //初始化敏感词检测
            SensitiveWordUtil.initMap(allSensitive);
            //敏感词过滤
            Map<String, Integer> sensitiveResult = SensitiveWordUtil.matchWords(contentAndImagesResult.get("content").toString());
            if (sensitiveResult!=null && sensitiveResult.size()>0){
                //有敏感词  不能通过  状态更新为  2
                updateWmNews(wmNews,(short)2,"文章中包含了敏感词:"+sensitiveResult);
                return;
            }
            //3阿里云文字 检测
            try {
                Map textMapResult = greenTextScan.greenTextScan(contentAndImagesResult.get("content").toString());
                if (textMapResult!=null && textMapResult.get("suggestion").equals("block")){
                    //审核未通过
                    updateWmNews(wmNews, (short) 2, "文本中内容有敏感词汇");
                    return;
                }
                if (textMapResult!=null && textMapResult.get("suggestion").equals("review")){
                    //需要人工审核
                    updateWmNews(wmNews, (short) 3, "文本中内容需要人工审核");
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("文章阿里云内容审核失败，转入人工审核, e：{}",e);
                updateWmNews(wmNews, (short) 3, "文章阿里云内容审核失败,转入需要人工审核");
            }
            //4阿里云图片检测
            if(contentAndImagesResult.get("image")!=null ||contentAndImagesResult.size()!=0){
                try {
                    //获取所有需要检测的图片
                    List<String> images =(List<String>) contentAndImagesResult.get("image");
                    //去除重复的图片
                    images = images.stream().distinct().collect(Collectors.toList());
                    //检测
                    Map imageMapResult = greenImageScan.imageUrlScan(images);
                    if (imageMapResult!=null && imageMapResult.get("suggestion").equals("block")){
                        updateWmNews(wmNews, (short) 2, "文章内有违规图片");
                        return;
                    }
                    if (imageMapResult!=null && imageMapResult.get("suggestion").equals("review")){
                        updateWmNews(wmNews, (short) 3, "文章图片有不确定元素,需转入人工人工审核");
                        return;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("阿里云图片检测失败 需要转入人工审核  文章id ==》{}",wmNews.getId());
                    updateWmNews(wmNews, (short) 3, "阿里云审核失败，转入人工审核");
                }
            }
            //审核都通过 =====到这
            //5判断文章发布时间大于当前时间，修改状态8
            if (wmNews.getPublishTime().after(new Date())){
                updateWmNews(wmNews,(short) 8,"等到发布时间，再发布");
                return;
            }
            //审核通过 发布文章   保存文章相关信息（三张表）， 修改文章的状态=9 已发布
            publishArticle(wmNews);
        }
    }


    //修改文章状态
    private void updateWmNews(WmNews wmNews, short status, String reason) {
        wmNews.setStatus(status);
        wmNews.setReason(reason);
        ResponseResult responseResult = wemediaFeign.updateWmNews(wmNews);
        if(!responseResult.getCode().equals(0)){
            log.error("自媒体文章更新失败  文章id==》{}",wmNews.getId());
            throw new CustomException(AppHttpCodeEnum.WEMEDIA_UPDATE_ERROR);
        }
    }


    //抽出文章中的文字以及图片  进行审核
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        String content = wmNews.getContent();
        //取出文字内容
        List<Map> contentMapList = JSON.parseArray(content, Map.class);
        String contentTextStr = contentMapList.stream().filter(map -> map.get("type").equals("text")).map(map -> (String) map.get("value"))
                .collect(Collectors.joining("_cheng_"));
        //需要检测的文字内容
        String contentText = contentTextStr + "_cheng_" + wmNews.getTitle();

        //抽出检测的图片
        //文章内容中的图片
        List<String> images = contentMapList.stream().filter(map -> map.get("type").equals(WemediaConstants.WM_NEWS_TYPE_IMAGE)).map(map -> (String) map.get("value"))
                .collect(Collectors.toList());
        //封面中的图片
        String coverImages = wmNews.getImages();
        if (StringUtils.isNotBlank(coverImages)){
            String[] splitImages = coverImages.split(",");
            for (String splitImage : splitImages) {
                images.add(webSite+splitImage);
            }
        }
        //封装结果 到map集合
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("content",contentText);
        resultMap.put("image",images);
        return resultMap;
    }


    //发布文章
    private void publishArticle(WmNews wmNews) {
        //保存app相关文章
        ResponseResult responseResult = saveArticle(wmNews);
        if (!responseResult.getCode().equals(0)){
            throw new CustomException(AppHttpCodeEnum.SERVER_ERROR,"保存app文章信息失败");
        }
        //保存文章id 到 WmNews
        wmNews.setArticleId((Long) responseResult.getData());
        updateWmNews(wmNews,(short)9,"文章审核通过");

    }


    //保存文章信息（包括文章信息，文章配置 文章内容 3张表）
    private ResponseResult saveArticle(WmNews wmNews) {

        //封装信息到dto
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setId(null);
        if (wmNews.getArticleId()!=null){
            articleDto.setId(wmNews.getArticleId());
        }
        //作者信息
        WmUser wmUser = wemediaFeign.findWmUserById(wmNews.getUserId());
        if (wmUser==null || wmUser.getStatus().intValue()!=9){
            log.error("作者用户不可用，或者不存在");
            throw new CustomException(AppHttpCodeEnum.NO_OPERATOR_AUTH,"作者不存在，或者被禁用");
        }
        if (StringUtils.isNotBlank(wmUser.getName())) {
            articleDto.setAuthorName(wmUser.getName());
        }
        //频道信息
        if (wmNews.getChannelId()!=null){
            articleDto.setChannelId(wmNews.getChannelId());
            AdChannel channel = adChannelMapper.selectById(wmNews.getChannelId());
            if (channel!=null){
                articleDto.setChannelName(channel.getName());
            }
        }
        //布局
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag((byte)0);
        //内容
        articleDto.setContent(wmNews.getContent());

        // 发起远程调用 保存 三张表数据, 返回值必须携带文章id
        return articleFeign.saveArticle(articleDto);
    }
}